package outputviewer;

import guiobjects.*;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Scanner;
import javax.swing.Timer;

import javax.swing.JFrame;


public class ObserveOutput
{
    // constants
    private final Dimension SIZE = new Dimension(600, 600);
    public final String TITLE = "Display of Output";
    private int frameRate = 60;
    private ArrayList<ReadDataThread> threadList = new ArrayList<ReadDataThread>();
    private ArrayList<ArrayList<ArrayList<IPaintedObject>>> myObservationArray = new ArrayList<ArrayList<ArrayList<IPaintedObject>>>();
    
    public void CreateApplet(String fileName)
    {
    	CreateApplet(fileName, "");
    }
    public void CreateApplet(String fileName, String completeMessage)
    {
    	int thisIndex = myObservationArray.size();
    	threadList.add(new ReadDataThread(fileName, completeMessage, thisIndex));
    	myObservationArray.add(new ArrayList<ArrayList<IPaintedObject>>());
    	threadList.get(thisIndex).start();
    }
    private class ReadDataThread extends Thread
    {
    	String myFileName;
    	String myCompleteMessage;
    	int myIndexToAdd;
    	private ReadDataThread(String fileName, String completeMessage, int indexToAdd)
    	{
    		myFileName = fileName;
    		myCompleteMessage = completeMessage;
    		myIndexToAdd = indexToAdd;
    	}
    	public void run()
    	{
    		myObservationArray.set(myIndexToAdd, processOutputFile(myFileName));
    		System.out.println(myCompleteMessage);
    	}
    }
    public void start()
    {
    	for (int i = 0; i < threadList.size(); i++)
    	{
    		while (threadList.get(i).isAlive())
    		{
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
    		}
    	}
    	System.out.println("Done reading.");
    	Applet app = new Applet();
        app.init(SIZE);

        // create container that will work with Window manager
        JFrame frame = new JFrame(TITLE);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // add our user interface components to Frame and show it
        frame.getContentPane().add(app, BorderLayout.CENTER);
        
        final Canvas thisCanvas = app.getCanvas(myObservationArray, frameRate);
        Buttons b = new Buttons(thisCanvas);
        frame.getContentPane().add(b, BorderLayout.SOUTH);
        
        frame.pack();        
        frame.setVisible(true);
        
        Timer myTimer = new Timer(250, 
                new ActionListener()
                {
            	    public void actionPerformed(ActionEvent e)
            	    {
            	    	thisCanvas.repaint();
            	    }
            	});
        myTimer.start();
        
    }
    private ArrayList<ArrayList<IPaintedObject>> processOutputFile(String dirName)
    {
        ArrayList<ArrayList<IPaintedObject>> output = new ArrayList<ArrayList<IPaintedObject>>();
        output.add(new ArrayList<IPaintedObject>());
        try
        {
            File file = new File(dirName);

            ArrayList<IPaintedObject> thisFrame = new ArrayList<IPaintedObject>();
            Scanner in = new Scanner(file);

            if (in.hasNextInt())
            	frameRate = in.nextInt();
            
            
            int lastFrame = 1;
            while (in.hasNext())
            {
            	String objectType = in.next();
                int frameNumber = in.nextInt();
                String definingString = in.nextLine();
                
                IPaintedObject thisObservation = getObject(objectType, definingString);
                
                boolean addedToAll = false;
                if (lastFrame != frameNumber)
                {
                	if (frameNumber == 0)
                	{
                		output.get(0).add(thisObservation);
                		addedToAll = true;
                	}
                	else
                	{
	                    lastFrame = frameNumber;
	                    output.add(thisFrame);
	                    thisFrame = new ArrayList<IPaintedObject>();
                	}
                }
                if (!addedToAll)
                	thisFrame.add(thisObservation);
                
            }
            output.add(thisFrame);
            
        }
        catch (Exception e)
        {
        	e.printStackTrace();
        }
        return output;
    }
    private static IPaintedObject getObject(String objectType, String definingString)
    {
    	IPaintedObject returnObject = null;
    	if (objectType.equals("Observation"))
    		returnObject = new Observation();
    	else if (objectType.equals("Text"))
    		returnObject = new Text();
    	else if (objectType.equals("Line"))
    		returnObject = new Line();
    	else if (objectType.equals("Circle"))
    		returnObject = new Circle();
    	else if (objectType.equals("Rectangle"))
    		returnObject = new Rectangle();
    	
    	returnObject.parseText(definingString);
    	return returnObject;
    }
}
